package com.nineclock.sign.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.attendance.pojo.AttendGroup;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.DateTimeUtil;
import com.nineclock.sign.dto.SignInfoDTO;
import com.nineclock.sign.dto.SignPCListDTO;
import com.nineclock.sign.mapper.SignPCListMapper;
import com.nineclock.sign.pojo.SignInfo;
import com.nineclock.sign.service.SignListService;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.feign.SysOrganizationFeign;
import com.nineclock.system.feign.SysUserFeign;
import com.nineclock.system.pojo.SysCompanyUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class SignListServiceImpl implements SignListService {

    @Autowired
    SignPCListMapper signPCListMapper;
    @Autowired
    SysUserFeign userFeign;
    @Autowired
    SysOrganizationFeign organizationFeign;


    @Override
    public PageResult<SignPCListDTO> querySignList(Integer page, Integer pageSize, String startTime, String endTime) {
        /***
         * 获取当前线程的企业管理员 肯定只是只查询当前他企业下的所有人员的签到信息
         * 根据企业id 去签到信息表里进行查询 获取所有的签到人员信息 获取到userid
         * 通过userid 远程调用去companyUser表进行查询  查到姓名usernam 工号worknumber 部门department name 职位post
         * 创建签到信息对象  SignInfoDTO 对前端传进来的签到日期进行查询  每个日期都有对应的签到次数 根据日期进行分组 统计每个员工的签到次数
         *
         */
        if (startTime == null || endTime == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //分页查询   建立返回前端的页面对象
        Page<SignInfo> signInfoPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<SignInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SignInfo::getCompanyId, CurrentUserHolder.get().getCompanyId());
        signInfoPage = signPCListMapper.selectPage(signInfoPage, wrapper);
        //获取pageresult里面的records数据 是一个list集合 转换为封装属性要传给前端的具体实体类  再对里面的属性一一设置
        List<SignInfo> signInfoList = signInfoPage.getRecords();
        if (CollectionUtil.isNotEmpty(signInfoList)) {


            List<SignPCListDTO> signPCListDTOList = new ArrayList<>();
            //根据id集合查询用户信息 查询出所有的员工信息
            List<SysCompanyUserDTO> sysCompanyUserDTOS = organizationFeign.queryAllUserByCompanyId(CurrentUserHolder.get().getCompanyId()).getData();
            if (CollectionUtil.isNotEmpty(sysCompanyUserDTOS)) {
                for (SysCompanyUserDTO sysCompanyUserDTO : sysCompanyUserDTOS) {

                    SignPCListDTO signPCListDTO = BeanHelper.copyProperties(sysCompanyUserDTO, SignPCListDTO.class);
                    //不一样的属性值单独设置
                    signPCListDTO.setUsername(sysCompanyUserDTO.getUserName());
                    //设置部门  远程调用根据userid查询 部门名称
                    SysDepartmentDTO sysDepartmentDTO1 = new SysDepartmentDTO();
                    sysDepartmentDTO1.setName(sysCompanyUserDTO.getDepartmentName());
                    sysDepartmentDTO1.setId(sysCompanyUserDTO.getDepartmentId());

                    signPCListDTO.setDepartment(sysDepartmentDTO1);

                    List<SignInfoDTO> signs = new ArrayList<>();//封装日期和签到次数


                    //获取当前传入的日期集合
                    List<String> signTimeList = this.getSpanDateList(startTime, endTime);
                    //遍历集合对属性进行设置
                    for (String s : signTimeList) {
                        //每天 都新建 封装签到信息对象  设置签到次数和签到时间
                        SignInfoDTO signInfoDTO = new SignInfoDTO();
                        LambdaQueryWrapper<SignInfo> wrapper1 = new LambdaQueryWrapper<>();
                        wrapper1.eq(SignInfo::getCompanyId, sysCompanyUserDTO.getCompanyId());
                        //企业员工id 和 企业员工表里的 id 对应查询
                        wrapper1.eq(SignInfo::getCompanyUserId, sysCompanyUserDTO.getId());
                        wrapper1.eq(SignInfo::getCreateDate,s);
                        //获取考勤次数
                        Integer integer = signPCListMapper.selectCount(wrapper1);
                        signInfoDTO.setSignDate(s);
                        signInfoDTO.setSignCount(integer);
                        signs.add(signInfoDTO);
                    }


                    signPCListDTO.setSigns(signs);

                    signPCListDTOList.add(signPCListDTO);
                }
            }

            return new PageResult(signInfoPage.getTotal(), signInfoPage.getPages(), signPCListDTOList);
        }

        return new PageResult();
    }

    public List<String> getSpanDateList(String startTime, String endTime) {
        //获取 时间 段内的每一天 日期 集合
        List<Date> dateList = DateTimeUtil.getDatesBetweenTwoDate(startTime, endTime, "yyyy-MM-dd");
        //转换为  字符串日期格式的集合
        List<String> dateStrList = dateList.stream().map(date -> {
            return DateUtil.format(date, "yyyy-MM-dd");
        }).collect(Collectors.toList());

        return dateStrList;
    }

}
